﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Objects;
using System.Globalization;
using System.Linq;
using EstateNuke.Data.Properties;

namespace EstateNuke.Data
{
    public partial class Property
    {
        #region Fileds & Properties

        /// <summary>
        /// </summary>
        public string DisplayName
        {
            get
            {
                if (!FloorReference.IsLoaded)
                {
                    FloorReference.Load(MergeOption.PreserveChanges);
                }
                return string.Format("{0}-{1}{2}", Floor.DisplayName, Name, IsDeleted ? " (已删除)" : "");
            }
        }

        /// <summary>
        /// </summary>
        public LeaseOrder ActiveLeaseOrder
        {
            get
            {
                if (!ActiveLeaseAgreementReference.IsLoaded)
                {
                    ActiveLeaseAgreementReference.Load(MergeOption.PreserveChanges);
                }
                return ActiveLeaseAgreement != null ? ActiveLeaseAgreement.LeaseOrder : null;
            }
        }

        /// <summary>
        /// </summary>
        public LeaseContract ActiveLeaseContract
        {
            get
            {
                if (!ActiveLeaseAgreementReference.IsLoaded)
                {
                    ActiveLeaseAgreementReference.Load(MergeOption.PreserveChanges);
                }
                return ActiveLeaseAgreement != null ? ActiveLeaseAgreement.LeaseContract : null;
            }
        }

        /// <summary>
        /// </summary>
        public LeaseCancellation ActiveLeaseCancellation
        {
            get
            {
                if (!ActiveLeaseAgreementReference.IsLoaded)
                {
                    ActiveLeaseAgreementReference.Load(MergeOption.PreserveChanges);
                }
                return ActiveLeaseAgreement != null ? ActiveLeaseAgreement.LeaseCancellation : null;
            }
        }

        /// <summary>
        /// </summary>
        public IList<PropertyPicture> PropertyPictures
        {
            get
            {
                return InternalPropertyPictures.Where(propertyPicture => propertyPicture.IsDeleted == false).ToList();
            }
        }

        /// <summary>
        /// </summary>
        public IList<LeaseAgreement> LeaseAgreements
        {
            get
            {
                return InternalLeaseAgreements.Where(leaseAgreement => leaseAgreement.IsDeleted == false).ToList();
            }
        }

        #endregion

        #region Set PropertyState

        /// <summary>
        /// </summary>
        public void SetPropertyStateLeasable(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            PropertyStateId = 1;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        /// <summary>
        /// </summary>
        public void SetPropertyStateReserved(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            PropertyStateId = 2;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        /// <summary>
        /// </summary>
        public void SetPropertyStateOrdered(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            PropertyStateId = 3;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        /// <summary>
        /// </summary>
        public void SetPropertyStateContracted(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            PropertyStateId = 4;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        #endregion

        #region Add & Remove PropertyPicture

        /// <summary>
        /// </summary>
        /// <returns></returns>
        public PropertyPicture AddPropertyPicture(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            var propertyPicture = new PropertyPicture
                                      {
                                          RowId = Guid.NewGuid(),
                                          CreatedDate = DateTime.Now,
                                      };
            InternalPropertyPictures.Add(propertyPicture);
            propertyPicture.IsDeleted = false;
            propertyPicture.ModifiedDate = DateTime.Now;
            propertyPicture.ModifiedByUser = modifiedUser;
            return propertyPicture;
        }

        /// <summary>
        /// </summary>
        /// <param name = "propertyPicture"></param>
        /// <param name = "modifiedUser"></param>
        public void RemovePropertyPicture(PropertyPicture propertyPicture, User modifiedUser)
        {
            if (propertyPicture == null)
            {
                throw new ArgumentNullException("propertyPicture");
            }
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (InternalPropertyPictures.Contains(propertyPicture))
            {
                propertyPicture.Delete(modifiedUser);
            }
        }

        #endregion

        #region Add & Remove LeaseAgreement

        /// <summary>
        /// </summary>
        /// <returns></returns>
        internal LeaseAgreement AddLeaseAgreement(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            var leaseAgreement = new LeaseAgreement
                                     {
                                         RowId = Guid.NewGuid(),
                                         CreatedDate = DateTime.Now,
                                     };
            InternalLeaseAgreements.Add(leaseAgreement);
            leaseAgreement.IsDeleted = false;
            leaseAgreement.ModifiedDate = DateTime.Now;
            leaseAgreement.ModifiedByUser = modifiedUser;
            leaseAgreement.SerialNumber = string.Format("SN{0}", DateTime.Now.ToString("yyyyMMddHHmmss"));
            leaseAgreement.LeaseAgreementStateId = 0;
            return leaseAgreement;
        }

        /// <summary>
        /// </summary>
        /// <param name = "leaseAgreement"></param>
        /// <param name = "modifiedUser"></param>
        internal void RemoveLeaseAgreement(LeaseAgreement leaseAgreement, User modifiedUser)
        {
            if (leaseAgreement == null)
            {
                throw new ArgumentNullException("leaseAgreement");
            }
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (InternalLeaseAgreements.Contains(leaseAgreement))
            {
                leaseAgreement.Delete(modifiedUser);
            }
        }

        #endregion

        #region Create Active LeaseOrder

        /// <summary>
        /// </summary>
        /// <returns></returns>
        public LeaseOrder CreateActiveLeaseOrder(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (PropertyStateId != 1)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateLeaseOrder, "房间不是可售状态"));
            }
            if (!ActiveLeaseAgreementReference.IsLoaded)
            {
                ActiveLeaseAgreementReference.Load(MergeOption.PreserveChanges);
            }
            if (ActiveLeaseAgreement != null && ActiveLeaseAgreement.LeaseAgreementStateId >= 1)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateLeaseOrder, "当前协议不是未售状态"));
            }
            if (ActiveLeaseAgreement == null)
            {
                ActiveLeaseAgreement = AddLeaseAgreement(modifiedUser);
            }
            return ActiveLeaseAgreement.CreateLeaseOrder(modifiedUser);
        }

        #endregion

        #region Create Active LeaseContract

        /// <summary>
        /// </summary>
        /// <returns></returns>
        public LeaseContract CreateActiveLeaseContract(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (PropertyStateId != 1 && PropertyStateId != 3)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateLeaseContract, "房间不是可售或预定状态"));
            }
            if (!ActiveLeaseAgreementReference.IsLoaded)
            {
                ActiveLeaseAgreementReference.Load(MergeOption.PreserveChanges);
            }
            if (ActiveLeaseAgreement != null && ActiveLeaseAgreement.LeaseAgreementStateId >= 2)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateLeaseContract, "当前协议不是未售或预定状态"));
            }
            if (ActiveLeaseAgreement == null)
            {
                ActiveLeaseAgreement = AddLeaseAgreement(modifiedUser);
            }
            return ActiveLeaseAgreement.CreateLeaseContract(modifiedUser);
        }

        #endregion

        #region Create Active LeaseCancellation

        /// <summary>
        /// </summary>
        /// <returns></returns>
        public LeaseCancellation CreateActiveLeaseCancellation(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            if (PropertyStateId != 1 && PropertyStateId != 3 && PropertyStateId != 4)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateLeaseCancellation, "房间不是可售、预定或已租状态"));
            }
            if (!ActiveLeaseAgreementReference.IsLoaded)
            {
                ActiveLeaseAgreementReference.Load(MergeOption.PreserveChanges);
            }
            if (ActiveLeaseAgreement != null && ActiveLeaseAgreement.LeaseAgreementStateId >= 4)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.CannotCreateLeaseCancellation, "当前协议不是未售、预定或已租状态"));
            }
            if (ActiveLeaseAgreement == null)
            {
                ActiveLeaseAgreement = AddLeaseAgreement(modifiedUser);
            }
            return ActiveLeaseAgreement.CreateLeaseCancellation(modifiedUser);
        }

        #endregion

        #region Ensure

        /// <summary>
        /// </summary>
        public void Ensure()
        {
            if (string.IsNullOrEmpty(Name))
            {
                throw new EntityException(string.Format(CultureInfo.CurrentCulture, Resources.NotNullAllowed, RowId, "Property", "Name"));
            }
            if (LeaseArea < 0)
            {
                throw new EntityException(string.Format(CultureInfo.CurrentCulture, Resources.NonNegativeNumberAllowed, RowId, "Property", "LeaseArea"));
            }
            if (UnitPricePerMonth < 0)
            {
                throw new EntityException(string.Format(CultureInfo.CurrentCulture, Resources.NonNegativeNumberAllowed, RowId, "Property", "UnitPricePerMonth"));
            }
            if (TotalPricePerMonth < 0)
            {
                throw new EntityException(string.Format(CultureInfo.CurrentCulture, Resources.NonNegativeNumberAllowed, RowId, "Property", "TotalPricePerMonth"));
            }
            Name = Name.Length > 64 ? Name.Substring(0, 64) : Name;
            Description = string.IsNullOrEmpty(Description) ? null : Description.Length > 512 ? Description.Substring(0, 512) : Description;
        }

        #endregion

        #region Delete

        /// <summary>
        /// </summary>
        public void Delete(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            IsDeleted = true;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
            ((List<PropertyPicture>) PropertyPictures).ForEach(propertyPicture => propertyPicture.Delete(modifiedUser));
            ((List<LeaseAgreement>) LeaseAgreements).ForEach(agreement => agreement.Delete(modifiedUser));
        }

        /// <summary>
        /// </summary>
        public void CancelDelete(User modifiedUser)
        {
            if (modifiedUser == null)
            {
                throw new ArgumentNullException("modifiedUser");
            }
            IsDeleted = false;
            ModifiedDate = DateTime.Now;
            ModifiedByUser = modifiedUser;
        }

        #endregion
    }
}